package org.ourgrid.broker.commands;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.ourgrid.broker.commands.executors.AcceptTransferExecutor;
import org.ourgrid.broker.commands.executors.AddJobExecutor;
import org.ourgrid.broker.commands.executors.CancelTransferExecutor;
import org.ourgrid.broker.commands.executors.DisposeWorkerExecutor;
import org.ourgrid.broker.commands.executors.FinishRequestExecutor;
import org.ourgrid.broker.commands.executors.GetFileInfoExecutor;
import org.ourgrid.broker.commands.executors.GetFilesExecutor;
import org.ourgrid.broker.commands.executors.ISchedulerCommandExecutor;
import org.ourgrid.broker.commands.executors.JobEndedExecutor;
import org.ourgrid.broker.commands.executors.LoggerExecutor;
import org.ourgrid.broker.commands.executors.OperationSucceedExecutor;
import org.ourgrid.broker.commands.executors.PauseRequestExecutor;
import org.ourgrid.broker.commands.executors.RemoteExecuteExecutor;
import org.ourgrid.broker.commands.executors.ReportReplicaAccountingExecutor;
import org.ourgrid.broker.commands.executors.RequestWorkersExecutor;
import org.ourgrid.broker.commands.executors.ResumeRequestExecutor;
import org.ourgrid.broker.commands.executors.StartTransferExecutor;
import org.ourgrid.broker.commands.executors.StartWorkExecutor;
import org.ourgrid.broker.commands.executors.UnwantWorkerExecutor;
import org.ourgrid.broker.commands.executors.UpdateSchedulerExecutor;

import br.edu.ufcg.lsd.commune.container.servicemanager.ServiceManager;

public class CommandExecutor {
	
	public static final String ACCEPT_TRANSFER = "ACCEPT_TRANSFER";
	public static final String ADD_JOB = "ADD_JOB";
	public static final String CANCEL_TRANSFER = "CANCEL_TRANSFER";
	public static final String DISPOSE_WORKER = "DISPOSE_WORKER";
	public static final String FINISH_REQUEST = "FINISH_REQUEST";
	public static final String GET_FILE_INFO = "GET_FILE_INFO";
	public static final String GET_FILES = "GET_FILES";
	public static final String JOB_ENDED = "JOB_ENDED";
	public static final String LOGGER = "LOGGER";
	public static final String OPERATION_SUCCEED = "OPERATION_SUCCEED";
	public static final String PAUSE_REQUEST = "PAUSE_REQUEST";
	public static final String REMOTE_EXECUTE = "REMOTE_EXECUTE";
	public static final String REPORT_ACCOUNTING = "REPORT_ACCOUNTING";
	public static final String REQUEST_WORKERS = "REQUEST_WORKERS";
	public static final String RESUME_REQUEST = "RESUME_REQUEST";
	public static final String START_TRANSFER = "START_TRANSFER";
	public static final String START_WORK = "START_WORK";
	public static final String UNWANT_WORKER = "UNWANT_WORKER";
	public static final String UPDATE_SCHEDULER = "UPDATE_SCHEDULER";

	private static CommandExecutor instance;
	private Map<String, ISchedulerCommandExecutor> dataExecutor;
	
	
	private CommandExecutor() {
		initMap();
	}
	
	public static CommandExecutor getInstance() {
		if (instance == null) {
			instance = new CommandExecutor();
		}
		return instance;
	}
	
	private void initMap() {
		
		this.dataExecutor = new LinkedHashMap<String, ISchedulerCommandExecutor>();
		
		this.dataExecutor.put(ACCEPT_TRANSFER, new AcceptTransferExecutor());
		this.dataExecutor.put(ADD_JOB, new AddJobExecutor());
		this.dataExecutor.put(CANCEL_TRANSFER, new CancelTransferExecutor());
		this.dataExecutor.put(DISPOSE_WORKER, new DisposeWorkerExecutor());
		this.dataExecutor.put(FINISH_REQUEST, new FinishRequestExecutor());
		this.dataExecutor.put(GET_FILE_INFO, new GetFileInfoExecutor());
		this.dataExecutor.put(GET_FILES, new GetFilesExecutor());
		this.dataExecutor.put(JOB_ENDED, new JobEndedExecutor());
		this.dataExecutor.put(LOGGER, new LoggerExecutor());
		this.dataExecutor.put(OPERATION_SUCCEED, new OperationSucceedExecutor());
		this.dataExecutor.put(PAUSE_REQUEST, new PauseRequestExecutor());
		this.dataExecutor.put(REMOTE_EXECUTE, new RemoteExecuteExecutor());
		this.dataExecutor.put(REPORT_ACCOUNTING, new ReportReplicaAccountingExecutor());
		this.dataExecutor.put(REQUEST_WORKERS, new RequestWorkersExecutor());
		this.dataExecutor.put(RESUME_REQUEST, new ResumeRequestExecutor());
		this.dataExecutor.put(START_TRANSFER, new StartTransferExecutor());
		this.dataExecutor.put(START_WORK, new StartWorkExecutor());
		this.dataExecutor.put(UNWANT_WORKER, new UnwantWorkerExecutor());
		this.dataExecutor.put(UPDATE_SCHEDULER, new UpdateSchedulerExecutor());
	}
	
	public void addExecutor(String actionName, ISchedulerCommandExecutor executor) {
		this.dataExecutor.put(actionName, executor);
	}
	
	public ISchedulerCommandExecutor getExecutor(String actionName) {
		return this.dataExecutor.get(actionName);
	}
	
	public void execute(List<SchedulerData> data, ServiceManager manager) {
		
		if (data != null) {
			for (SchedulerData schedulerData : data) {
				getExecutor(schedulerData.getActionName()).execute(schedulerData, manager);
			}
		}	
	}
}
